package com.xbongbong.parent.explain;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.domain.entity.ext.FieldPermissionEntityExt;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateNodeEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.NodeTypeEnum;
import com.xbongbong.paas.enums.VisibleTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.VisibleRulePoJo;
import com.xbongbong.paas.field.VisibleRuleVO;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataFormExplainHelper;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.model.PaasProcessTemplateNodeModel;
import com.xbongbong.paas.model.StageProcessModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.abstracts.AbstractFormExplainHandleName;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.PaasStageEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormOwnerUniqueEnum;
import com.xbongbong.pro.enums.workflow.TriggerEventTypeEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.OrderOutStockEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.product.BusinessProductCompareEnum;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.SysUserHelp;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.enums.WorkflowNodeTypeEnum;
import com.xbongbong.workflow.model.WorkflowModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.pojo.nodes.FormTriggerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author: wufeng
 * @date: 2018/11/30 15:25
 * @desrcption: 表单新建数据过滤字段
 */
@Component
public class FormDataAddFormExplainHandlerName extends AbstractFormExplainHandleName {

    private static final Logger LOG = LoggerFactory.getLogger(FormDataAddFormExplainHandlerName.class);

    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private FormDataFormExplainHelper formDataFormExplainHelper;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private PaasProcessTemplateNodeModel paasProcessTemplateNodeModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private WorkflowModel workflowModel;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private StageProcessModel stageProcessModel;
    @Resource
    private SysUserHelp sysUserHelp;
    @Override
    public HandlerExplainVO handleExplain(HandlerExplainDTO handlerExplainDTO) throws XbbException {
        HandlerExplainVO handlerExplainVO;
        try {
            List<FieldAttrEntity> explainList = handlerExplainDTO.getExplainList();
            PaasFormEntityExt paasFormEntityExt = handlerExplainDTO.getPaasFormEntityExt();
            Integer count = 0;
            List<PaasProcessTemplateEntityExt> processTemplateList = new ArrayList<>();
            List<WorkflowEntity> workflowList = new ArrayList<>();
            String corpid = handlerExplainDTO.getCorpid();
            Map<String, Object> processTemplateParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            processTemplateParam.put(StringConstant.CORPID, corpid);
            processTemplateParam.put("del", DelEnum.NORMAL.getDel());
            processTemplateParam.put("formId", paasFormEntityExt.getId());
            processTemplateParam.put("appId", paasFormEntityExt.getAppId());
            processTemplateParam.put("enable", 1);
            processTemplateParam.put("usePermission", 1);
            boolean isWorkflow = commonHelp.isOpenWorkFlow(corpid);
            if (isWorkflow) {
                processTemplateParam.put("currentVersion", 1);
                processTemplateParam.put("isApprove", 1);
                processTemplateParam.put("triggerEventTypeIn", Arrays.asList(TriggerEventTypeEnum.ONLY_ADD.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
                processTemplateParam.put(ParameterConstant.COLUMNS, " enable, id ");
                processTemplateParam.put(ParameterConstant.ORDER_BY_STR, "priority asc");
                workflowList = workflowModel.findEntitys(processTemplateParam);
                count = workflowList.size();
            } else {

                processTemplateParam.put(ParameterConstant.COLUMNS, " enable, id ");
                processTemplateList = paasProcessTemplateModel.list(processTemplateParam);
                count = processTemplateList.size();
            }


            // 根据表单的权限剔除字段
            Integer isProcessForm = paasFormEntityExt.getIsProcessForm();
            if(Objects.equals(isProcessForm, 0) || Objects.equals(count, 0) || Objects.equals(handlerExplainDTO.getIsOuterLink(), 1)){
                handlerExplainVO = getExplainList(explainList, handlerExplainDTO);
            } else if (isWorkflow) {
                WorkflowNodeEntity workflowNodeEntity = workflowNodeModel.getByUId(workflowList.get(0).getId(), corpid, WorkflowNodeTypeEnum.START_NODE.getName());
                FormTriggerNode formTriggerNode = JSON.parseObject(workflowNodeEntity.getConfigData(), FormTriggerNode.class);
                handlerExplainVO = getExplainInApprove(explainList, handlerExplainDTO, formTriggerNode.getFieldPermission(), true);
            } else{
                PaasProcessTemplateEntityExt paasProcessTemplateEntityExt = processTemplateList.get(0);
                handlerExplainVO = getExplainListByFieldPermission(explainList, handlerExplainDTO, paasProcessTemplateEntityExt);
            }
            handleExplainDefaultLimit(handlerExplainVO, handlerExplainDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e){
            LOG.error("FormDataFormExplainHandleName.handleExplain处理字段中的部门、角色、用户等名称报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return handlerExplainVO;
    }

    /**
     * 渲染字段中的用户，部门，角色，并且根据流程节点字段权限过滤不可见字段
     * @param explainList
     * @param handlerExplainDTO
     * @return
     * @throws XbbException
     */
    public HandlerExplainVO getExplainListByFieldPermission(List<FieldAttrEntity> explainList, HandlerExplainDTO handlerExplainDTO,
                                                             PaasProcessTemplateEntityExt paasProcessTemplateEntityExt) throws XbbException {
        try {
            PaasFormEntityExt paasFormEntityExt = handlerExplainDTO.getPaasFormEntityExt();

            Map<String, Object> param = BeanUtil.convertBean2Map(handlerExplainDTO, true);
            param.put(StringConstant.CORPID, handlerExplainDTO.getCorpid());
            param.put("type", NodeTypeEnum.START_PROCESS_NODE.getNodeType());
            param.put("appId", paasFormEntityExt.getAppId());
            param.put("formId", paasFormEntityExt.getId());
            param.put("templateId", paasProcessTemplateEntityExt.getId());
            List<PaasProcessTemplateNodeEntityExt> nodeList = paasProcessTemplateNodeModel.list(param);
            if(nodeList == null || nodeList.isEmpty()){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }
            PaasProcessTemplateNodeEntityExt templateNode = nodeList.get(0);
            List<FieldPermissionEntityExt> fieldPermissionList = templateNode.getFieldPermissionList();
            Map<String, FieldPermissionEntityExt> fieldPermissionMap = new HashMap<>(fieldPermissionList.size());
            fieldPermissionList.forEach((item)->{
                String attr = item.getAttr();
                if (StringUtil.isNotEmpty(item.getSubAttr())) {
                    attr = attr + StringConstant.POINT + item.getSubAttr();
                }
                fieldPermissionMap.put(attr, item);
            });
            return getExplainInApprove(explainList, handlerExplainDTO, fieldPermissionMap, false);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("FormDataFormExplainHandleName.getExplainListByFieldPermission处理字段中的部门、角色、用户等名称报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 审批或者工作流，字段回显
     * @param explainList
     * @param handlerExplainDTO
     * @param fieldPermissionMap
     * @param workflowTag 工作流标识 true:是  false:否
     * @return
     * @throws XbbException
     */
    private HandlerExplainVO getExplainInApprove(List<FieldAttrEntity> explainList, HandlerExplainDTO handlerExplainDTO,Map<String, FieldPermissionEntityExt> fieldPermissionMap, boolean workflowTag) throws XbbException{
        HandlerExplainVO handlerExplainVO = new HandlerExplainVO();
        try {
            //需要处理的几个工作流放出关联产品字段的业务
            List<Integer> workflowProductBusList = BusinessProductCompareEnum.getProductHandleBusList();
            boolean shouldHanldTag = workflowProductBusList.contains(handlerExplainDTO.getBusinessType()) && workflowTag;
            PaasFormEntityExt paasFormEntityExt = handlerExplainDTO.getPaasFormEntityExt();
            List<FieldAttrEntity> list = new ArrayList<>();
            //用户集合
            Map<String, UserEntity> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            //部门集合
            Map<String, DepartmentEntity> departmentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            //角色集合
            Map<String, RoleEntity> roleMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            handlerExplainDTO.setPermissionMap(fieldPermissionMap);
            // 获取该公司下该套餐下的功能信息
            List<String> featureList = packageHelp.getFeatureList(handlerExplainDTO.getCorpid());
            handlerExplainDTO.setFeatureList(featureList);
            for (FieldAttrEntity entity: explainList) {
//                if (Objects.equals(entity.getFieldType(), FieldTypeEnum.SEPARATOR.getType()) || Objects.equals(entity.getFieldType(), FieldTypeEnum.MEMO.getType())) {
//                    list.add(entity);
//                    continue;
//                }
                // 允许可见，则处理以下规则
                FieldPermissionEntityExt permissionEntity = fieldPermissionMap.get(entity.getAttr());
                if (Objects.equals(entity.getIsRedundant(), 0) && permissionEntity == null) {
                    // 处理团队成员放出 回款单、付款单、应收款、付款计划、联系人、供应商联系人 负责人和协同人 字段后老数据
                    if (Objects.equals(entity.getAttr(), "ownerId") || Objects.equals(entity.getAttr(), "coUserId")) {
                        entity.setVisible(BasicConstant.ONE);
                    }
                    list.add(entity);
                    continue;
                }
                // 可见即可编辑 产品定的
                Integer visible = 0;
                if (Objects.nonNull(permissionEntity)) {
                    visible = permissionEntity.getVisible();
                }
                if (Objects.equals(entity.getFieldType(),FieldTypeEnum.LABEL.getType())){
                    proFormHelp.setLabelDefaultValue(entity,handlerExplainDTO.getCorpid());
                }
                //if(entity.getVisible().equals(visible)){
                if(FieldTypeEnum.SUB_FORM.getType().equals(entity.getFieldType()) || FieldTypeEnum.CONTACT_NUMBER.getType().equals(entity.getFieldType())
                 || (Objects.equals(entity.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType())
                        || Objects.equals(FieldTypeEnum.SELECT_SERVICE.getType(), entity.getFieldType())
                        && shouldHanldTag)){
                    setSubFieldAttrEntity(entity, handlerExplainDTO, userMap, departmentMap, roleMap);
                }else{
                    setFieldAttrEntity(entity, handlerExplainDTO, userMap, departmentMap, roleMap);
                }
                List<VisibleRuleVO> userVoList = new ArrayList<>();
                if (Objects.nonNull(entity.getVisibleScopeRule())) {
                    VisibleRulePoJo visibleRulePoJo = new VisibleRulePoJo();
                    entity.setVisibleScopeRule(visibleRulePoJo);
                    entity.getVisibleScopeRule().setUserList(userVoList);
                }
                entity.setVisible(visible);
                //退货退款中合计退款金额不允许编辑
                boolean isRefundAmount = Objects.equals(handlerExplainDTO.getBusinessType(), XbbRefTypeEnum.REFUND.getCode()) && Objects.equals(entity.getAttr(), RefundEnum.REFUND_AMOUNT.getAttr());
                boolean isReturnedPurchaseAmount = Objects.equals(handlerExplainDTO.getBusinessType(), XbbRefTypeEnum.RETURNED_PURCHASE.getCode()) && Objects.equals(entity.getAttr(), ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr());
                if (isRefundAmount || isReturnedPurchaseAmount) {
                    visible = 0;
                }
                if (Objects.equals(handlerExplainDTO.getBusinessType(), XbbRefTypeEnum.CLUE.getCode()) && Objects.equals(entity.getAttr(), ClueEnum.CLUE_STATUS.getAttr())) {
                    // 线索状态不允许编辑
                    visible = 0;
                }
                // 都是人才 其他出入库单业务类型不允许编辑
                if ((Objects.equals(handlerExplainDTO.getBusinessType(),XbbRefTypeEnum.OTHER_OUTSTOCK.getCode()) && Objects.equals(entity.getAttr(), OutstockEnum.TYPE.getAttr())) ||
                        (Objects.equals(handlerExplainDTO.getBusinessType(),XbbRefTypeEnum.OTHER_INSTOCK.getCode()) && Objects.equals(entity.getAttr(), InstockEnum.TYPE.getAttr()))){
                    visible = 0;
                }
                //出库发货单中的收货人和寄件人的电话和地址不允许编辑
                if (Objects.equals(handlerExplainDTO.getBusinessType(),XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode()) && Objects.equals(handlerExplainDTO.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode()) &&
                        (Objects.equals(entity.getAttr(), OrderOutStockEnum.RECEIPT_PHONE.getAttr()) || Objects.equals(entity.getAttr(), OrderOutStockEnum.RECEIPT_ADDRESS.getAttr()) ||
                                Objects.equals(entity.getAttr(), OrderOutStockEnum.SEND_PHONE.getAttr()) || Objects.equals(entity.getAttr(), OrderOutStockEnum.SEND_ADDRESS.getAttr()))){
                    visible = 0;
                }

                //判断阶段推进器新建人可编辑权限 外链不需要判断这个权限
                if (Objects.equals(entity.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType()) && !Objects.equals(handlerExplainDTO.getIsOuterLink(), BasicConstant.ONE)) {
                    entity.setEditable(judgeStageNewSelect(explainList, handlerExplainDTO.getCorpid(), paasFormEntityExt.getId(), handlerExplainDTO.getUserId()) ? visible : BasicConstant.ZERO);
                } else {
                    entity.setEditable(visible);
                }
                //赢率字段值是自动算出来的，不能编辑
                if (Objects.equals(entity.getAttr(), PaasStageEnum.STAGE_RATIO.getAttr())) {
                    entity.setEditable(BasicConstant.ZERO);
                }
                entity.setItems(proFormHelp.setItem(entity, paasFormEntityExt));
                if (Objects.equals(entity.getFieldType(),FieldTypeEnum.SELECT_PRODUCT.getType())){
                    proFormHelp.setProductAccuracy(entity,handlerExplainDTO.getCorpid(), handlerExplainDTO.getUserId());
                    setSubFieldAttrEntity(entity, handlerExplainDTO, userMap, departmentMap, roleMap);
                }
                // 套餐逻辑，标准版本隐藏复杂字段
                packageHelp.explainHide(featureList, entity);
                // 套餐逻辑，数据联动和联动其他表单
                packageHelp.setPackageLimit(featureList, entity);
                // 限制公式
                packageHelp.limitFormula(featureList, entity, handlerExplainDTO.getBusinessType());
                // 字段回收站处理
                if (Objects.equals(entity.getIsOpen(), 2)) {
                    entity.setVisible(0);
                }
                list.add(entity);
                //} else {
                //entity.setVisible(visible);
                //list.add(entity);
                //}
            }
            handlerExplainVO.setUserMap(userMap);
            handlerExplainVO.setDepartmentMap(departmentMap);
            handlerExplainVO.setHeadList(list);
            return handlerExplainVO;
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("FormDataFormExplainHandleName.getExplainListByFieldPermission处理字段中的部门、角色、用户等名称报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }
    /**
     * 渲染字段中的用户，部门，角色，并且根据表单过滤不可见字段
     * @param explainList
     * @return
     * @throws XbbException
     */
    @Override
    public HandlerExplainVO getExplainList(List<FieldAttrEntity> explainList, HandlerExplainDTO handlerExplainDTO) throws XbbException{
        PaasFormEntityExt paasFormEntityExt = handlerExplainDTO.getPaasFormEntityExt();
        HandlerExplainVO handlerExplainVO = new HandlerExplainVO();
        //用户集合
        Map<String, UserEntity> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //部门集合
        Map<String, DepartmentEntity> departmentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //角色集合
        Map<String, RoleEntity> roleMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> featureList = packageHelp.getFeatureList(handlerExplainDTO.getCorpid());
        handlerExplainDTO.setFeatureList(featureList);
        List<FieldAttrEntity> list = new ArrayList<>();
        //团队成员上线之后负责人唯一跟套餐相关了
        List<Integer> allBusinessList = FormOwnerUniqueEnum.getAllBusinessList();
        Integer feeType = commonHelp.getCurrentCompanyPackage(handlerExplainDTO.getCorpid());
        boolean teamOwnerUniqueTag = !Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType()) && allBusinessList.contains(handlerExplainDTO.getBusinessType());
        try {
            for (FieldAttrEntity entity: explainList) {
                // 允许可见，则处理以下规则

                List<VisibleRuleVO> userVoList = new ArrayList<>();
                if (Objects.equals(entity.getIsOpen(), 0)) {
                    // 非扩展字段，并且未开启时，字段不能显示在列表上
                    continue;
                }
                if (Objects.equals(entity.getFieldType(),FieldTypeEnum.SELECT_PRODUCT.getType())){
                    proFormHelp.setProductAccuracy(entity,handlerExplainDTO.getCorpid(), handlerExplainDTO.getUserId());
                }
                if (Objects.equals(entity.getFieldType(),FieldTypeEnum.LABEL.getType())){
                    proFormHelp.setLabelDefaultValue(entity,handlerExplainDTO.getCorpid());
                }
                // 套餐逻辑，标准版本隐藏复杂字段
                packageHelp.explainHide(featureList, entity);
                // 套餐逻辑，数据联动和联动其他表单
                packageHelp.setPackageLimit(featureList, entity);
                // 公式限制
                packageHelp.limitFormula(featureList, entity, handlerExplainDTO.getBusinessType());
                // 高级可见规则回显用户名称
                if (ExplainUtil.invisibleOfScope(entity, handlerExplainDTO)) {
                    entity.setVisible(0);
                }
                // 新建页面的渲染（可编辑）不需要高级规则，所以这里不校验
                if(ExplainUtil.isSubForm(entity.getFieldType())){
                    setSubFieldAttrEntity(entity, handlerExplainDTO, userMap, departmentMap, roleMap);
                }else{
                    setFieldAttrEntity(entity, handlerExplainDTO, userMap, departmentMap, roleMap);
                }
                // 可编辑，添加编辑权限
                Boolean editFlag = ExplainUtil.isEditableOfScope(entity, handlerExplainDTO);
                Integer editable = editFlag ? 1 : 0;
                //在表单设计设置可编辑的前提下，校验阶段推进器字段的新建编辑人权限
                if (Objects.nonNull(paasFormEntityExt) && Objects.equals(FieldTypeEnum.STAGE_THRUSTER.getType(), entity.getFieldType()) && Objects.equals(editable, 1) && !Objects.equals(handlerExplainDTO.getIsOuterLink(), BasicConstant.ONE)) {
                    editable = judgeStageNewSelect(explainList, paasFormEntityExt.getCorpid(), paasFormEntityExt.getId(), handlerExplainDTO.getUserId()) ? 1 : 0;
                }
                entity.setEditable(editable);
                if (Objects.nonNull(entity.getVisibleScopeRule())) {
                    entity.getVisibleScopeRule().setUserList(userVoList);
                }
                if (Objects.nonNull(paasFormEntityExt)) {
                    entity.setItems(proFormHelp.setItem(entity, paasFormEntityExt));
                }
                // 字段回收站处理
                if (Objects.equals(entity.getIsOpen(), 2)) {
                    entity.setVisible(0);
                }
                if (teamOwnerUniqueTag && Objects.equals(FieldTypeEnum.OWNERID.getAlias(), entity.getAttr())) {
                    entity.setMultiple(FormOwnerUniqueEnum.getFormOwnerUniqueByBus(handlerExplainDTO.getBusinessType()).getValue());
                }
                list.add(entity);

            }
            handlerExplainVO.setUserMap(userMap);
            handlerExplainVO.setDepartmentMap(departmentMap);
            handlerExplainVO.setHeadList(list);
        }catch (XbbException e) {
            throw e;
        }catch (Exception e) {
            LOG.error("FormDataAddFormExplainHandleName.getExplainList处理字段中的部门、角色、用户等名称报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return handlerExplainVO;
    }

    /**
     * 设置子表单字段属性
     * @param entity
     * @param userMap
     * @param departmentMap
     * @param roleMap
     * @return
     * @throws XbbException
     */
    @Override
    public FieldAttrEntity setSubFieldAttrEntity(FieldAttrEntity entity, HandlerExplainDTO handlerExplainDTO, Map<String, UserEntity> userMap,
                                                 Map<String, DepartmentEntity> departmentMap, Map<String, RoleEntity> roleMap) throws XbbException{
        if (Objects.isNull(entity.getSubForm())){
            return entity;
        }
        boolean isWorkflow = commonHelp.isOpenWorkFlow(handlerExplainDTO.getCorpid());
        boolean handleProductBus = BusinessProductCompareEnum.getProductHandleBusList().contains(handlerExplainDTO.getBusinessType());
        boolean trueHandBusTag = isWorkflow && handleProductBus && Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), entity.getFieldType());
        List<? extends FieldAttrEntity> subExplainList = entity.getSubForm().getItems();
        List<FieldAttrEntity> subFieldAttrList = new ArrayList<>();
        try {
            if(subExplainList == null){
                entity.getSubForm().setItems(new ArrayList<>());
                return entity;
            }
            Map<String, FieldPermissionEntityExt> permissionMap = handlerExplainDTO.getPermissionMap();
            Iterator<? extends FieldAttrEntity> iterator = subExplainList.iterator();
            while (iterator.hasNext()){
                FieldAttrEntity subFieldAttrEntity = iterator.next();
                if(Objects.isNull(permissionMap)) {
                    // 如果是表单的可编辑/可见权限
                    if (ExplainUtil.invisibleOfScope(subFieldAttrEntity, handlerExplainDTO)) {
                        subFieldAttrEntity.setVisible(0);
                    }
                    if (!ExplainUtil.isEditableOfScope(subFieldAttrEntity, handlerExplainDTO)) {
                        subFieldAttrEntity.setEditable(0);
                    }
                }
                // 新建页面的渲染不需要（可编辑）高级规则，所以这里不校验
                subFieldAttrEntity = setFieldAttrEntity(subFieldAttrEntity, handlerExplainDTO, userMap, departmentMap, roleMap);
                // 开始节点的权限读取
                if (Objects.nonNull(permissionMap)) {
                    String attr = entity.getAttr()+ StringConstant.POINT + subFieldAttrEntity.getAttr();
                    FieldPermissionEntityExt permissionEntity = permissionMap.get(attr);
                    if(permissionEntity != null){
                        if ( Objects.equals(permissionEntity.getVisible(),0) ){
                            subFieldAttrEntity.setEditable(0);
                            subFieldAttrEntity.setVisible(0);
                        } else if (Objects.nonNull(permissionEntity.getVisible()) && Objects.equals(1, permissionEntity.getVisible())) {
                            // 首节点，可见即可编辑
                            // 本次发现存在{"attr": "array_4", "subAttr": "num_5", "summary": 0, "editable": 0, "fieldType": 2}数据，所以增加判断visible是否为null
                            //需要兼容本身有一些关联产品字段是不能编辑的字段，所以这边需要兼容一下
                            if (trueHandBusTag) {
                                List<String> unEditableFieldList = BusinessProductCompareEnum.getAllUnEditableFieldList(handlerExplainDTO.getBusinessType());
                                if (unEditableFieldList.contains(subFieldAttrEntity.getAttr())) {
                                    subFieldAttrEntity.setEditable(BasicConstant.ZERO);
                                }else {
                                    subFieldAttrEntity.setEditable(BasicConstant.ONE);
                                }
                                subFieldAttrEntity.setVisible(1);
                            }else {
                                subFieldAttrEntity.setEditable(1);
                                subFieldAttrEntity.setVisible(1);
                            }
                        }
                    }
                } else {
                    // 可编辑，添加编辑权限
                    Boolean editFlag = ExplainUtil.isEditableOfScope(subFieldAttrEntity, handlerExplainDTO);
                    Integer editable = editFlag ? 1 : 0;
                    subFieldAttrEntity.setEditable(editable);
                }
                // 套餐逻辑，标准版本隐藏复杂字段
                packageHelp.explainHide(handlerExplainDTO.getFeatureList(), subFieldAttrEntity);
                // 套餐逻辑，数据联动和联动其他表单
                packageHelp.setPackageLimit(handlerExplainDTO.getFeatureList(), subFieldAttrEntity);
                // 限制公式
                packageHelp.limitFormula(handlerExplainDTO.getFeatureList(), subFieldAttrEntity, handlerExplainDTO.getBusinessType());
                // 字段回收站处理
                if (Objects.equals(subFieldAttrEntity.getIsOpen(), 2)) {
                    subFieldAttrEntity.setVisible(0);
                }
                subFieldAttrList.add(subFieldAttrEntity);
            }
            entity.getSubForm().setItems(subFieldAttrList);
        } catch (Exception e) {
            LOG.error("AbstractFormExplainHandleName.setFieldAttrEntity：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return entity;
    }

    /**
     * 设置字段的属性，回显用户名称，部门名称，角色名称，已经关联表的字段信息
     * @param entity 字段对象
     * @param userMap 用户容器
     * @param departmentMap 部门容器
     * @param roleMap 角色容器
     * @return 返回填充的字段信息
     * @throws XbbException 抛出业务异常
     */
    @Override
    public FieldAttrEntity setFieldAttrEntity(FieldAttrEntity entity, HandlerExplainDTO handlerExplainDTO,Map<String, UserEntity> userMap,
                                              Map<String, DepartmentEntity> departmentMap, Map<String, RoleEntity> roleMap) throws XbbException{
        try {
            if (Objects.nonNull(entity.getDefaultAttr())) {
                List<OptionalRangeEntity> defaultList = entity.getDefaultAttr().getDefaultList();
                if(defaultList != null && !defaultList.isEmpty()){
                    defaultList = formDataFormExplainHelper.handleOptionalRangeList(defaultList, handlerExplainDTO.getCorpid(), userMap, departmentMap, roleMap);
                    entity.getDefaultAttr().setDefaultList(defaultList);
                }
            }

            // 可新增，添加可新增权限，负责人和协同人字段才有可新增
            if (Objects.equals(entity.getFieldType(), FieldTypeEnum.OWNERID.getType()) || Objects.equals(entity.getFieldType(), FieldTypeEnum.COUSERID.getType())) {
                Integer add = Objects.nonNull(entity.getAdd()) ? entity.getAdd() : BasicConstant.IS_USE;
                if (Objects.equals(BasicConstant.IS_USE, add)) {
                    Integer addAdvanceEnable = entity.getAddAdvanceEnable();
                    if (Objects.equals(BasicConstant.IS_USE, addAdvanceEnable)) {
                        VisibleRulePoJo addRule = entity.getAddRule();
                        if (Objects.nonNull(addRule)) {
                            Integer addType = addRule.getType();
                            VisibleTypeEnum addTypeEnum = VisibleTypeEnum.getByType(addType);
                            switch (addTypeEnum) {
                                case NOT_SHOW_ANYONE:
                                    if (ExplainUtil.notShowAnyOne(addRule, handlerExplainDTO)) {
                                        add = BasicConstant.NO_USE;
                                    }
                                    break;
                                case SOME_PEOPLE_CAN_SEE:
                                    if (ExplainUtil.fieldCanSee(addRule, handlerExplainDTO)) {
                                        add = BasicConstant.NO_USE;
                                    }
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
                entity.setAdd(add);
            }

        }catch (Exception e){
            LOG.error("AbstractFormExplainHandleName.setFieldAttrEntity：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return entity;
    }

    /**
     * 新建阶段推进器数据判断能否编辑阶段推进器字段
     * @param explainList
     * @param corpid
     * @param formId
     * @param userId
     * @return
     */
    private Boolean judgeStageNewSelect(List<FieldAttrEntity> explainList, String corpid, Long formId, String userId) throws XbbException {
        try {
            StageProcessEntity stageProcessEntity;
            // 判断是否多版本启用，如果是多版本启用，那么获取默认的版本
            FieldAttrEntity stageField = explainList.stream().filter(field -> Objects.equals(field.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType())).findFirst().orElse(null);
            if (Objects.nonNull(stageField) && Objects.equals(stageField.getStageMultiVersion(), 1) && Objects.nonNull(stageField.getDefaultStageProcessId())) {
                stageProcessEntity = stageProcessModel.getByKey(stageField.getDefaultStageProcessId(), corpid);
            } else {
                stageProcessEntity = stageProcessModel.getEnableStageProcess(corpid, formId);
            }
            if (Objects.nonNull(stageProcessEntity)) {
                if (Objects.equals(stageProcessEntity.getAllowNewSelect(), BasicConstant.ONE)) {
                    if (CollectionsUtil.isNotEmpty(stageProcessEntity.getAllowNewSelectUser())) {
                        List<OptionalRangeEntity> optionalRangeEntities = JSON.parseArray(JSON.toJSONString(stageProcessEntity.getAllowNewSelectUser()), OptionalRangeEntity.class);
                        Set<String> userList = sysUserHelp.getUserListByOptionalRange(corpid, optionalRangeEntities, new JSONObject(), "");
                        return userList.contains(userId);
                    }
                } else {
                    return false;
                }
            }
        } catch (Exception e) {
            LOG.error("FormDataAddFormExplainHandlerName.judgeStageNewSelect：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return true;
    }
}
